﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <functional>
using namespace std;

namespace wmz
{
	//template <class T>
	//class auto_ptr
	//{
	//public:
	//	auto_ptr(T* ptr) :_ptr(ptr)
	//	{

	//	}
	//	//const不行
	//	auto_ptr(auto_ptr<T>& sp)
	//	{
	//		_ptr = sp._ptr;
	//		sp._ptr = nullptr;
	//	}
	//	auto_ptr<T>& operator=(auto_ptr<T>& ap)
	//	{
	//		//不是自己赋值
	//		if (this != &ap)
	//		{
	//			//删除本身自己的资源
	//			if (_ptr)
	//				delete _ptr;
	//			_ptr = ap._ptr;
	//			ap._ptr = nullptr;
	//		}
	//		return *this;
	//		
	//	}
	//	~auto_ptr()
	//	{
	//		if (_ptr)
	//		{
	//			delete _ptr;
	//		}
	//	}
	//	T* operator->()
	//	{
	//		return _ptr;
	//	}
	//	T& operator*()
	//	{
	//		return *_ptr;
	//	}
	//private:
	//	T* _ptr;
	//};

	//template<class T>
	//class unique_ptr
	//{
	//public:
	//	explicit unique_ptr(T* ptr) :_ptr(ptr)
	//	{

	//	}
	//	unique_ptr(const unique_ptr<T>& up) = delete;
	//	unique_ptr& operator=(const unique_ptr<T>& up) = delete;
	//	unique_ptr(unique_ptr<T>&& up)
	//		:_ptr(up._ptr)
	//	{
	//		up._ptr = nullptr;
	//	}
	//	unique_ptr& operator=(unique_ptr<T>&& up)
	//	{
	//		delete _ptr;
	//		_ptr = up._ptr;
	//		up._ptr = nullptr;
	//	}
	//	~unique_ptr()
	//	{
	//		if (_ptr)
	//			delete _ptr;
	//	}
	//	T* operator->()
	//	{
	//		return _ptr;
	//	}
	//	T& operator*()
	//	{
	//		return *_ptr;
	//	}
	//private:
	//	T* _ptr;
	//};


	template <class T>
	class shared_ptr
	{
	public:
		shared_ptr(T* ptr) :_ptr(ptr),_count(new int(1))
		{

		}
		template<class D>
		shared_ptr(T* ptr, D del) : _ptr(ptr), _del(del)
		{

		}
		shared_ptr(const shared_ptr<T>& sp)
		{
			_ptr = sp._ptr;
			_count = sp._count;
			_del = sp._del;
			(*_count)++;

		}

		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (this != &sp)
			{
				--(*_count);
				if (*_count == 0)
				{
					_del(_ptr);
					delete _count;
				}
				_ptr = sp._ptr;
				_count = sp._count;
				_del = sp._del;
				(*_count)++;
			}
			return *this;
		}
		~shared_ptr()
		{
			(*_count)--;
			if (*_count == 0)
			{
				_del(_ptr);
				delete _count;
			}
		}
		T* get()
		{
			return _ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
		T& operator*()
		{
			return *_ptr;
		}
		int use_count()
		{
			return *_count;
		}
	private:
		T* _ptr;
		int* _count;
		function<void(T*)> _del = [](T* ptr) {delete ptr; };
	};

	template<class T>
	class weak_ptr
	{
	public:
		weak_ptr()
		{}
		weak_ptr(const shared_ptr<T>& sp) :_ptr(sp.get())
		{

		}
		weak_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			_ptr = sp.get();
			return *this;
		}

	private:
		T* _ptr = nullptr;
	};
}


struct ListNode
{
	int _data;
	std::shared_ptr<ListNode> _next;
	std::shared_ptr<ListNode> _prev;
	// 这⾥改成weak_ptr，当n1->_next = n2;绑定shared_ptr时
	// 不增加n2的引⽤计数，不参与资源释放的管理，就不会形成循环引⽤了
	/*std::weak_ptr<ListNode> _next;
	std::weak_ptr<ListNode> _prev;*/
	~ListNode()
	{
		cout << "~ListNode()" << endl;
	}
};
int main()
{
	// 循环引⽤ -- 内存泄露
	std::shared_ptr<ListNode> n1(new ListNode);
	std::shared_ptr<ListNode> n2(new ListNode);
	cout << n1.use_count() << endl;
	cout << n2.use_count() << endl;
	cout << n1->_next.use_count() << endl;
	cout << n1->_prev.use_count() << endl;
	cout << n2->_next.use_count() << endl;
	cout << n2->_prev.use_count() << endl;


	cout << n2->_prev.use_count() << endl;
	n1->_next = n2;
	n2->_prev = n1;
	cout << n1.use_count() << endl;
	cout << n2.use_count() << endl;
	cout << n1->_next.use_count() << endl;
	cout << n1->_prev.use_count() << endl;
	cout << n2->_next.use_count() << endl;
	cout << n2->_prev.use_count() << endl;
	// weak_ptr不⽀持管理资源，不⽀持RAII
	// weak_ptr是专⻔绑定shared_ptr，不增加他的引⽤计数，作为⼀些场景的辅助管理
	//std::weak_ptr<ListNode> wp(new ListNode);
	return 0;
}

//int main()
//{
//	//wmz::auto_ptr<int> ap = new int(10);
//	//cout << *ap << endl;
//	//wmz::auto_ptr<int> ap2 = ap;
//	//cout << *ap2 << endl;
//	//cout << *ap << endl;
//	//wmz::unique_ptr<int> up(new int(10));
//	//cout << *up << endl;
//	//wmz::unique_ptr<int> up1(up);
//	wmz::shared_ptr<int> sp(new int(10));
//	wmz::shared_ptr<int> sp1 = sp;
//
//	return 0;
//}